package com.gl.saasservice.sys.service;

import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import com.alibaba.fastjson.JSON;
import com.gl.common.util.Digests;
import com.gl.common.util.Encodes;
import com.gl.common.util.KeyWorker;
import com.gl.common.util.SecurityUtils;
import com.gl.common.vo.ApiData;
import com.gl.framework.security.LoginUser;
import com.gl.framework.web.response.Result;
import com.gl.portal.system.vo.SysUserVo;
import com.gl.saasservice.approvalprocess.entity.ApprovalProcessUser;
import com.gl.saasservice.approvalprocess.repository.ApprovalProcessDefinitionRepository;
import com.gl.saasservice.approvalprocess.repository.ApprovalProcessNodeRepository;
import com.gl.saasservice.approvalprocess.repository.ApprovalProcessRepository;
import com.gl.saasservice.approvalprocess.repository.ApprovalProcessUserRepository;
import com.gl.saasservice.area.entity.Area;
import com.gl.saasservice.area.service.AreaService;
import com.gl.saasservice.entity.*;
import com.gl.saasservice.house.entity.House;
import com.gl.saasservice.house.repository.HouseRepository;
import com.gl.saasservice.repository.*;
import com.gl.saasservice.sys.mapper.PermissionRowMapper;
import com.gl.saasservice.sys.utils.CheckUtil;
import com.gl.saasservice.sys.vo.*;
import com.haixiaoke.saas.repository.pojo.OrgElectronicVisa;
import com.haixiaoke.saas.repository.service.IOrgElectronicVisaService;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.jdbc.core.BeanPropertyRowMapper;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.transaction.interceptor.TransactionAspectSupport;

import java.util.*;
import java.util.stream.Collectors;

/**
 *
 */
@Service
public class DepartmentService {
    private static final Logger LOG = LoggerFactory.getLogger(DepartmentService.class);

    @Autowired
    private DepartmentRepository departmentRepository;
    @Autowired
    private DepartmentHierarchyRepository departmentHierarchyRepository;
    @Autowired
    private RoleRepository roleRepository;
    @Autowired
    private QYUserRepository qYUserRepository;
    @Autowired
    private JdbcTemplate jdbcTemplate;
    @Autowired
    private UserRoleRepository userRoleRepository;
    @Autowired
    private UserDepartmentRepository userDepartmentRepository;
    @Autowired
    private AreaService areaService;
    @Autowired
    private DepartmentEnterpriseTagRefRepository departmentEnterpriseTagRefRepository;
    @Autowired
    private DepartmentEnterpriseTagRepository departmentEnterpriseTagRepository;
    @Autowired
    private DepartmentTagRepository departmentTagRepository;
    @Autowired
    private ApprovalProcessNodeRepository approvalProcessNodeRepository;
    @Autowired
    private ApprovalProcessDefinitionRepository approvalProcessDefinitionRepository;
    @Autowired
    private ApprovalProcessRepository approvalProcessRepository;
    @Autowired
    private ApprovalProcessUserRepository approvalProcessUserRepository;
    @Autowired
    private UserRepository userRepository;
    @Autowired
    private ServerUserRepository serverUserRepository;
    @Autowired
    private FieldManagementRepository fieldManagementRepository;
    @Autowired
    private FieldStatusRefRepository fieldStatusRefRepository;
    @Autowired
    private DepartmentBillRepository departmentBillRepository;
    @Autowired
    private HouseRepository houseRepository;
    @Autowired
    private SmartLockRepository smartLockRepository;
    @Autowired
    private IOrgElectronicVisaService orgElectronicVisaService;


    public Map<String, Object> pages(String accessToken, DepartmentVO filter) throws Exception {
        LOG.info("DepartmentService pages accessToken={},filter={}", accessToken, JSON.toJSONString(filter));

        String mobile = filter.getMobile();
        Map<String, Object> map = new HashMap<String, Object>();
        List<DepartmentHierarchyVO> departmentHierarchyVOS = new ArrayList<>();
        if (StrUtil.isNotEmpty(mobile)) {
            StringBuffer user = new StringBuffer(
                    "SELECT * FROM saas_user WHERE (`status` = 1 OR `status`= 0) AND type = 1 AND mobile LIKE");
            user.append("'%" + mobile+ "%'");

            List<User> userList = jdbcTemplate.query(user.toString(), new BeanPropertyRowMapper<>(User.class));
            if (CollectionUtil.isNotEmpty(userList)) {
                for (User user1 : userList) {
                    StringBuffer list = new StringBuffer(
                            "SELECT * FROM saas_user WHERE (`status` =1 OR `status`= 0) AND type = 1 AND mobile  = ");
                    list.append(user1.getMobile());
                    List<User> userList1 = jdbcTemplate.query(list.toString(), new BeanPropertyRowMapper<>(User.class));
                    for (User user2 : userList1) {
                        String userId = user2.getId();
                        List<UserDepartment> byUserId = userDepartmentRepository.findByUserId(userId);
                        for (UserDepartment userDepartment : byUserId) {
                            DepartmentHierarchyVO departmentHierarchyVO = new DepartmentHierarchyVO();
                            Long depId = userDepartment.getDepId();
                            DepartmentHierarchy byOrgId = departmentHierarchyRepository.findByOrgId(depId);
                            if (byOrgId != null) {
                                BeanUtils.copyProperties(byOrgId,departmentHierarchyVO);
                                departmentHierarchyVOS.add(departmentHierarchyVO);
                            }
                        }
                    }
                }
            }
        }
        StringBuffer sql = new StringBuffer(
                "select id,org_id, parent_id,enterprise_tag_id,tag_id,name,area_id,auditor_user_id,code,sortby,status,last_update_time,merchants_type,bind_auit_status,apply_auit_status ,social_credit_number from saas_department_hierarchy WHERE 1=1 ");

        if (StringUtils.isNotBlank(filter.getDepartmentHierarchyVO().getName())) {
            sql.append(" AND name like ").append("'%" + filter.getDepartmentHierarchyVO().getName() + "%'");
        }

        if (StringUtils.isNotBlank(filter.getDepartmentHierarchyVO().getCode())) {
            sql.append(" AND code like ").append("'%" + filter.getDepartmentHierarchyVO().getCode() + "%'");
        }

        if (filter.getDepartmentHierarchyVO().getAreaId() != null) {

            List<Long> childAreaId = allChildByArea(filter.getDepartmentHierarchyVO().getAreaId());
            childAreaId.add(filter.getDepartmentHierarchyVO().getAreaId());

            StringBuffer area = new StringBuffer();  //substring(, currentApprovalProcess.)

            childAreaId.forEach(a -> {
                area.append(a).append(",");
            });
            String areasql = area.toString().substring(0, area.toString().lastIndexOf(","));

            sql.append(" AND area_id in ( ").append(areasql + " ) ");
        }

        if (filter.getDepartmentHierarchyVO().getStatus() != null) {
            sql.append(" AND status = ").append(filter.getDepartmentHierarchyVO().getStatus());
        }

        sql.append(" order by sortby");
        List<DepartmentHierarchyVO> dhlist = new ArrayList<>();
        //如果传了手机号过来就根据手机号查询的数据
        if (StrUtil.isNotEmpty(mobile)) {
            dhlist = departmentHierarchyVOS;
        } else {
            dhlist = jdbcTemplate.query(sql.toString(), new BeanPropertyRowMapper<>(DepartmentHierarchyVO.class));
        }
        //机构id
        List<Long> orgIdList = dhlist.stream().map(DepartmentHierarchyVO::getOrgId).collect(Collectors.toList());
        //区域id
        List<Long> areas = dhlist.stream().map(DepartmentHierarchyVO::getAreaId).collect(Collectors.toList());

        List<Area> areaList = areaService.findByIdIn(areas);
        //层级关系id
        List<Long> dhIds = dhlist.stream().map(DepartmentHierarchyVO::getId).collect(Collectors.toList());
        List<DepartmentEnterpriseTagRef> departmentEnterpriseTagRefList = departmentEnterpriseTagRefRepository.findByDepRefIdIn(dhIds);
        //获取所有企业标签
        Iterable<DepartmentEnterpriseTag> departmentEnterpriseTagList = departmentEnterpriseTagRepository.findAll();

        List<Department> departmentList = departmentRepository.findByIdIn(orgIdList);
        List<DepartmentVO> departmentVOList = new ArrayList<>();
        List<Long> depId = new ArrayList<>();
        departmentList.forEach(d -> {
            DepartmentVO departmentVO = new DepartmentVO();
            BeanUtils.copyProperties(d, departmentVO);
            depId.add(departmentVO.getId());
            departmentVOList.add(departmentVO);

        });
        //组织(部门)账单
        List<DepartmentBill> departmentBillList = departmentBillRepository.findByDepIdIn(depId);

        List<UserDepartment> userDepartmentList = userDepartmentRepository.findByDepIdIn(orgIdList);
        List<String> userIdList = userDepartmentList.stream().map(UserDepartment::getUserId).collect(Collectors.toList());
        List<User> userList = qYUserRepository.findByIdIn(userIdList);
        List<UserVO> userVOList = new ArrayList<>();
        userList.forEach(u -> {
            UserVO userVO = new UserVO();
            BeanUtils.copyProperties(u, userVO);
            userVOList.add(userVO);
        });

        List<Role> roleList = roleRepository.findByOrgIdInAndTypeAndProperty(orgIdList, 1, 2);
        List<RoleVO> roleVOList = new ArrayList<>();
        roleList.forEach(role -> {
            RoleVO roleVO = new RoleVO();
            BeanUtils.copyProperties(role, roleVO);
            roleVOList.add(roleVO);
        });
        List<Long> roles = roleList.stream().map(Role::getId).collect(Collectors.toList());
        List<UserRole> userRoles = userRoleRepository.findByRoleIdIn(roles);

        for (DepartmentHierarchyVO dh : dhlist) {

            for (DepartmentEnterpriseTagRef deTagRef : departmentEnterpriseTagRefList) {
                if (deTagRef.getDepRefId().equals(dh.getId())) {
                    dh.getEnterpriseTagIds().add(deTagRef.getTagId());
                }
            }

            for (Area a : areaList) {
                if (a.getId().equals(dh.getAreaId())) {
                    dh.setAreaName(a.getName());
                }
            }

            for (DepartmentVO d : departmentVOList) {
                if (d.getId().equals(dh.getOrgId())) {
                    dh.setDepartmentVO(d);

                    if (!departmentBillList.isEmpty()) {
                        for (DepartmentBill depBill : departmentBillList) {
                            if (depBill.getDepId().equals(d.getId())) {
                                dh.setBillStatus(depBill.getBillStatus());
                                dh.setSmartLockStatus(depBill.getSmartLockStatus());
                            }
                        }
                    }
                }
            }


            for (RoleVO roleVO : roleVOList) {
                if (dh.getOrgId().equals(roleVO.getOrgId())) {
                    dh.setRoleVO(roleVO);
                    for (UserRole userRole : userRoles) {  //查找主管理员
                        if (userRole.getRoleId().equals(roleVO.getId())) {
                            for (UserVO u : userVOList) {
                                if (userRole.getUserId().equals(u.getId())) {
                                    dh.setUserVO(u);
                                    break;
                                }
                            }

                        }

                    }
                }
            }

            Long orgId = dh.getOrgId();
            OrgElectronicVisa orgElectronicVisa = orgElectronicVisaService.selectOrgElectronicVisaByOrgId(orgId);
            if (ObjectUtil.isNull(orgElectronicVisa)) {
                dh.setElectronicVisaState(0);
            }else {
                dh.setElectronicVisaState(1);
                dh.setContractTotalNumber(orgElectronicVisa.getContractTotalNumber());
                dh.setContractUsedNumber(orgElectronicVisa.getContractUsedNumber());
            }

        }

        //判断如果是单位承租人、产权单位、房东机构，会多一个物业标签，删除不让展示
        /*for (DepartmentHierarchyVO departmentHierarchyVO : dhlist) {
            List<Long> enterpriseTagIds = departmentHierarchyVO.getEnterpriseTagIds();
            if (enterpriseTagIds.contains(2L) || enterpriseTagIds.contains(7L) || enterpriseTagIds.contains(8L)) {
                    for (int i = enterpriseTagIds.size() - 1; i >= 0; i--) {
                        Long aLong = enterpriseTagIds.get(i);
                        if (aLong == 4L) {
                            enterpriseTagIds.remove(i);
                            break;
                        }
                    }

            }
        }*/
        // 重排下结果
      /*  List<DepartmentVO> newList = new LinkedList<>();
        sortList(newList, departmentVOList);
        departmentVOList = newList;*/

        map.put("data", dhlist);
        return map;
    }

    private void sortList(List<DepartmentHierarchyVO> newList, List<DepartmentHierarchyVO> list) {
        for (DepartmentHierarchyVO vo : list) {
            if (vo.getParentId().longValue() == 0) {
                newList.add(vo);
                findChild(vo.getId(), newList, list);
            }
        }
    }

    private void findChild(Long parentId, List<DepartmentHierarchyVO> newList, List<DepartmentHierarchyVO> list) {
        for (DepartmentHierarchyVO vo : list) {
            if (parentId.longValue() == vo.getParentId().longValue()) {
                newList.add(vo);
                findChild(vo.getId(), newList, list);
            }
        }
    }

    @Transactional(rollbackFor = Exception.class)
    public Result save(String accessToken, DepartmentVO departmentVO) {
        LOG.info("DepartmentService save accessToken={},departmentVO={}", accessToken, JSON.toJSONString(departmentVO));
        DepartmentHierarchyVO departmentHierarchyVO = departmentVO.getDepartmentHierarchyVO();

        LoginUser loginUser = SecurityUtils.getLoginUser();
        SysUserVo sysUser = loginUser.getUser();

        CheckUtil checkUtil = new CheckUtil();
        checkUtil.checkValues(departmentVO);
        if (checkUtil.isNull()) {
            return Result.fail(checkUtil.getMessage());
        }
        //新增社会统一代码不能一致 xiaolong 20230330
        Long id = departmentVO.getId();
        if (id == null) {
            String socialCreditNumber = departmentVO.getSocialCreditNumber();
            if (socialCreditNumber != null) {
                List<DepartmentHierarchy> socialCreditNumberIsNotNull = departmentHierarchyRepository.findSocialCreditNumberIsNotNull(null);
                if (!socialCreditNumberIsNotNull.isEmpty()) {
                    for (DepartmentHierarchy departmentHierarchy : socialCreditNumberIsNotNull) {
                        if (departmentHierarchy.getSocialCreditNumber().equals(socialCreditNumber)) {
                            return Result.fail("社会统一代码不能一致");
                        }
                    }
                }
            }
        }
        //部门
        Department department = new Department();
        if (departmentVO.getId() == null) {
            department.setCode(buildCodeByDepartment(0L));
            department.setCreateTime(new Date());
            department.setActivateStatus(1);
            department.setStatus(1);
            department.setParentId(0L);
        } else {
            Optional<Department> departmentOptional = departmentRepository.findById(departmentVO.getId());
            if (!departmentOptional.isPresent()) {
                return Result.fail("当前数据不存在");
            }
            BeanUtils.copyProperties(departmentOptional.get(), department);
        }
        department.setName(departmentVO.getName());//部门名称
        if (departmentVO.getProvinceId() != null) {
            department.setProvinceId(departmentVO.getProvinceId());
        }
        if (departmentVO.getCityId() != null) {
            department.setCityId(departmentVO.getCityId());
        }
        if (departmentVO.getDistrictId() != null) {
            department.setDistrictId(departmentVO.getDistrictId());
        }
        if (departmentVO.getStreetId() != null) {
            department.setStreetId(departmentVO.getStreetId());
        }
        if (departmentVO.getCommunityId() != null) {
            department.setCommunityId(departmentVO.getCommunityId());
        }
        department.setSortby(departmentVO.getSortby());
        if (departmentHierarchyVO.getEnterpriseTagIds().contains(new Long(2))) {
            department.setOwnerType(1);
        } else {
            department.setOwnerType(2);
        }
        if (departmentHierarchyVO.getEnterpriseTagIds().contains(new Long(3))) {
            department.setType(2);
        } else {
            department.setType(1);
        }
        Department save = departmentRepository.save(department);

        Date date = new Date();

        // 电子签数量修改
        OrgElectronicVisa orgElectronicVisa = orgElectronicVisaService.selectOrgElectronicVisaByOrgId(save.getId());
        if (ObjectUtil.isNotNull(orgElectronicVisa)) {
            if (departmentVO.getContractTotalNumber() < orgElectronicVisa.getContractUsedNumber()) {
                TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
                return Result.fail("合同总数不能小于已使用合同数");
            }
            orgElectronicVisa.setContractTotalNumber(departmentVO.getContractTotalNumber());
            orgElectronicVisa.setUpdateTime(date);
            orgElectronicVisaService.updateOrgElectronicVisa(orgElectronicVisa);
        }

        //组织(部门)账单状态表
        DepartmentBill depBill = departmentBillRepository.findByDepId(save.getId());
        DepartmentBill departmentBill = new DepartmentBill();
        if (depBill != null ){
            BeanUtils.copyProperties(depBill,departmentBill);
            departmentBill.setLastUpdateTime(date);
            departmentBill.setOperatorId(sysUser.getId().toString());
        }else {
            departmentBill.setDepId(save.getId());
            departmentBill.setCreateTime(date);
            departmentBill.setLastUpdateTime(date);
            departmentBill.setOperatorId(sysUser.getId().toString());
        }
        departmentBill.setBillStatus(departmentVO.getBillStatus());
        departmentBill.setSmartLockStatus(departmentVO.getSmartLockStatus());
        departmentBillRepository.save(departmentBill);

        //机构层次
        DepartmentHierarchy departmentHierarchy = new DepartmentHierarchy();
        if (departmentHierarchyVO.getParentId() == null) {
            TransactionAspectSupport.currentTransactionStatus().setRollbackOnly(); //手工回滚异常
            return Result.fail("机构层级父级id不能为空");
        }
        DepartmentHierarchy hierarchySave;
        if (departmentHierarchyVO.getId() == null) {//新增
            //区域标签
            if (departmentHierarchyVO.getTagId() != null) {
                switch (departmentHierarchyVO.getTagId().toString()) {
                    case "1":
                        departmentHierarchy.setAreaId(departmentVO.getProvinceId());
                        break;
                    case "2":
                        departmentHierarchy.setAreaId(departmentVO.getCityId());
                        break;
                    case "3":
                        departmentHierarchy.setAreaId(departmentVO.getDistrictId());
                        break;
                    case "4":
                        departmentHierarchy.setAreaId(departmentVO.getStreetId());
                        break;
                    case "5":
                        departmentHierarchy.setAreaId(departmentVO.getCommunityId());
                        break;
                }
                List<DepartmentHierarchy> entitys = departmentHierarchyRepository.findByAreaIdAndName(departmentHierarchy.getAreaId(), departmentVO.getName());
                if (!entitys.isEmpty()) {
                    TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();//手工回滚异常
                    return Result.fail("部门名称已存在");
                }
            } else {
                List<DepartmentHierarchy> entitys = departmentHierarchyRepository.findByName(departmentVO.getName());
                if (!entitys.isEmpty()) {
                    TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();//手工回滚异常
                    return Result.fail("部门名称已存在");
                }
            }

            departmentHierarchy.setParentId(departmentHierarchyVO.getParentId());
            departmentHierarchy.setOrgId(save.getId());
            departmentHierarchy.setStatus(1);
            departmentHierarchy.setCode(buildCodeByDepartmentHierarchy(departmentHierarchyVO.getParentId()));
            departmentHierarchy.setTagId(departmentHierarchyVO.getTagId());
            departmentHierarchy.setName(save.getName());
            departmentHierarchy.setSortby(departmentVO.getSortby());
            departmentHierarchy.setLastUpdateTime(new Date());
            departmentHierarchy.setMerchantsType(1);//企业商户号收款
            //创建机构时新增单位社会信用证号
            departmentHierarchy.setSocialCreditNumber(departmentVO.getSocialCreditNumber());
            // 新增时审批状态处理
            if (departmentHierarchyVO.getEnterpriseTagIds().contains(new Long(5))) {
                departmentHierarchy.setBindAuitStatus(departmentHierarchyVO.getBindAuitStatus());
                departmentHierarchy.setApplyAuitStatus(departmentHierarchyVO.getApplyAuitStatus());
            } else {
                departmentHierarchy.setBindAuitStatus(null);
                departmentHierarchy.setApplyAuitStatus(null);
            }
            hierarchySave = departmentHierarchyRepository.save(departmentHierarchy);
        } else {//修改
            Optional<DepartmentHierarchy> departmentHierarchyOptional = departmentHierarchyRepository.findById(departmentHierarchyVO.getId());
            if (!departmentHierarchyOptional.isPresent()) {
                TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
                return Result.fail("当前数据已不存在");
            }
            BeanUtils.copyProperties(departmentHierarchyOptional.get(), departmentHierarchy);
            //下级code
            departmentHierarchy.setCode(buildCodeByDepartmentHierarchy(departmentHierarchyVO.getParentId()));
            departmentHierarchy.setTagId(departmentHierarchyVO.getTagId());
            departmentHierarchy.setName(save.getName());
            departmentHierarchy.setSortby(departmentVO.getSortby());
            departmentHierarchy.setLastUpdateTime(new Date());
            //区域标签
            if (departmentHierarchyVO.getTagId() != null) {
                switch (departmentHierarchyVO.getTagId().toString()) {
                    case "1":
                        departmentHierarchy.setAreaId(departmentVO.getProvinceId());
                        break;
                    case "2":
                        departmentHierarchy.setAreaId(departmentVO.getCityId());
                        break;
                    case "3":
                        departmentHierarchy.setAreaId(departmentVO.getDistrictId());
                        break;
                    case "4":
                        departmentHierarchy.setAreaId(departmentVO.getStreetId());
                        break;
                    case "5":
                        departmentHierarchy.setAreaId(departmentVO.getCommunityId());
                        break;
                }
                if (departmentHierarchyOptional.get().getAreaId() == null ||
                        (departmentHierarchyOptional.get().getAreaId() != null && departmentHierarchyOptional.get().getAreaId().longValue() != departmentHierarchy.getAreaId()) ||
                        !departmentHierarchyOptional.get().getName().equals(departmentHierarchy.getName())) {
                    List<DepartmentHierarchy> entitys = departmentHierarchyRepository.findByAreaIdAndName(departmentHierarchy.getAreaId(), departmentVO.getName());
                    if (!entitys.isEmpty()) {
                        TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();//手工回滚异常
                        return Result.fail("部门名称已存在");
                    }
                }
            } else {
                if (!departmentHierarchyOptional.get().getName().equals(departmentHierarchy.getName())) {
                    List<DepartmentHierarchy> entitys = departmentHierarchyRepository.findByName(departmentVO.getName());
                    if (!entitys.isEmpty()) {
                        TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();//手工回滚异常
                        return Result.fail("部门名称已存在");
                    }
                }
            }
            departmentHierarchy.setParentId(departmentHierarchyVO.getParentId());
            // 新增时审批状态处理
            if (departmentHierarchyVO.getEnterpriseTagIds().contains(new Long(5))) {
                departmentHierarchy.setBindAuitStatus(departmentHierarchyVO.getBindAuitStatus());
                departmentHierarchy.setApplyAuitStatus(departmentHierarchyVO.getApplyAuitStatus());
            } else {
                departmentHierarchy.setBindAuitStatus(null);
                departmentHierarchy.setApplyAuitStatus(null);
            }
            //创建机构时新增单位社会信用证号
            departmentHierarchy.setSocialCreditNumber(departmentVO.getSocialCreditNumber());
            hierarchySave = departmentHierarchyRepository.save(departmentHierarchy);

            String childCode = departmentHierarchyOptional.get().getCode();
            if (hierarchySave != null) {
                List<Long> idsList = allChildByHierarchy(hierarchySave.getId());
                List<DepartmentHierarchy> allDepartmentHierarchy = departmentHierarchyRepository.findByIdIn(idsList);
                for (DepartmentHierarchy childDepartmentHierarchy : allDepartmentHierarchy) {
                    StringBuffer buffer = new StringBuffer(childDepartmentHierarchy.getCode());
                    buffer.replace(0, childCode.length(), hierarchySave.getCode());
                    childDepartmentHierarchy.setCode(String.valueOf(buffer));
                    departmentHierarchyRepository.save(childDepartmentHierarchy);
                }
            }
        }

        //企业与标签关系
        if (departmentEnterpriseTagRefRepository.findByDepRefId(hierarchySave.getId()).size() > 0) {
            departmentEnterpriseTagRefRepository.deleteByDepRefId(hierarchySave.getId());
        }
        List<DepartmentEnterpriseTagRef> departmentEnterpriseTagRefList = new ArrayList<>();
        for (Long enterpriseTagId : departmentHierarchyVO.getEnterpriseTagIds()) {
            DepartmentEnterpriseTagRef departmentEnterpriseTagRef = new DepartmentEnterpriseTagRef();
            departmentEnterpriseTagRef.setDepRefId(hierarchySave.getId());
            departmentEnterpriseTagRef.setTagId(enterpriseTagId);
            departmentEnterpriseTagRefList.add(departmentEnterpriseTagRef);

        }

        departmentEnterpriseTagRefRepository.saveAll(departmentEnterpriseTagRefList);
        //角色
        Role role1Save = new Role();
        if (departmentVO.getId() == null) {
            //角色组
            Role role = new Role(); //默认
            role.setOrgId(save.getId());
            role.setParentId(0L);
            role.setName("默认");
            //role.setCode();
            role.setProperty(1);
            role.setNatureType(1);
            role.setPropertyType(1);
            Role roleSave = roleRepository.save(role);
            //角色
            Role role1 = new Role();//主管理员角色
            Role role2 = new Role();//子管理员角色
            role1.setOrgId(save.getId());
            role1.setParentId(roleSave.getId());
            role1.setName("主管理员");
            //role1.setCode();
            role1.setProperty(2);
            role1.setType(1);
            role1.setNatureType(1);

            role2.setOrgId(save.getId());
            role2.setParentId(roleSave.getId());
            role2.setName("子管理员");
            //role2.setCode();
            role2.setProperty(2);
            role2.setType(2);
            role2.setNatureType(1);

            role1Save = roleRepository.save(role1);
            roleRepository.save(role2);
        }

        //用户
        UserVO userVO = departmentVO.getUserVO();
        User user = new User();
        if (departmentVO.getId() == null) {
            User entity = qYUserRepository.findByMobile(userVO.getMobile());
            if (entity != null) {
                TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
                return Result.fail("手机号码重复");
            }
            user.setId("S" + KeyWorker.nextId());
            user.setEntryTime(new Date());
            user.setCreateTime(new Date());
            user.setPosition("主管理员");
            user.setType((short) 1);
            user.setStatus((short) 0);

            byte[] salt = Digests.generateSalt(8);
            String saltStr = Encodes.encodeHex(salt);
            user.setSalt(saltStr);
            byte[] hashPassword = Digests.sha1(userVO.getPassword().getBytes(), salt, 1024);
            String password = Encodes.encodeHex(hashPassword);
            user.setPassword(password);

        } else {
            Optional<User> userOptional = qYUserRepository.findById(userVO.getId());
            if (!userOptional.isPresent()) {
                TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
                return Result.fail("当前数据已不存在");
            }
            BeanUtils.copyProperties(userOptional.get(), user);

            //编辑密码保存时，如果页面传的密码字符串等于数据库加密后的字符串，就不用进行密码操作了
            if (!user.getPassword().equals(userVO.getPassword())) {
                byte[] salt = Digests.generateSalt(8);
                String saltStr = Encodes.encodeHex(salt);
                user.setSalt(saltStr);
                byte[] hashPassword = Digests.sha1(userVO.getPassword().getBytes(), salt, 1024);
                String password = Encodes.encodeHex(hashPassword);
                user.setPassword(password);
            }

            if (!user.getMobile().equals(userVO.getMobile())) {  //手机号有更新才验证
                User entity = qYUserRepository.findByMobile(userVO.getMobile());
                if (entity != null) {
                    TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
                    return Result.fail("手机号码重复");
                }
            }

            //更新同步维护App用户表
            List<AppUser> appUserList = userRepository.findByEnterpriseUserId(userVO.getId());  //app用户id和企业用户id相同
            if (!appUserList.isEmpty()) {
                for (AppUser appUser : appUserList) {
                    if (!appUser.getPhone().equals(userVO.getMobile())) {    //手机号有更新才验证
                        AppUser appEntity = userRepository.findByPhone(userVO.getMobile());
                        if (appEntity != null) {
                            TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
                            return Result.fail("手机号码重复");
                        }
                    }
                    appUser.setPhone(userVO.getMobile());
                    appUser.setSalt(user.getSalt());
                    appUser.setPassword(user.getPassword());

                    userRepository.save(appUser);

                }

            }
        }

        user.setName(userVO.getMobile());
        user.setMobile(userVO.getMobile());
        //新增 密码状态：1默认密码 2非默认密码 20230309 xiaolong
        user.setPasswordStatus(2);
        User qYUserSave = qYUserRepository.save(user);

        if (departmentVO.getId() == null) {//新增
            //角色用户
            UserRole userRole = new UserRole();
            userRole.setRoleId(role1Save.getId());
            userRole.setUserId(qYUserSave.getId());
            userRoleRepository.save(userRole);

            //部门用户
            UserDepartment userDepartment = new UserDepartment();
            userDepartment.setDepId(save.getId());
            userDepartment.setUserId(qYUserSave.getId());
            //userDepartment.setType(2);
            userDepartmentRepository.save(userDepartment);

            //新增企业时,插入通讯录默认字段管理表和企业默认字段状态关系表
            List<FieldManagement> fieldManagementList = fieldManagementRepository.findAll();
            List<Long> fieldIdList = fieldManagementList.stream().map(FieldManagement::getId).collect(Collectors.toList());

            List<FieldStatusRef> fieldStatusRefList = new ArrayList<>();
            for (Long fieldId : fieldIdList) {
                FieldStatusRef fieldStatusRef = new FieldStatusRef();

                fieldStatusRef.setOrgId(save.getId());
                fieldStatusRef.setDefaultFieldId(fieldId);
                fieldStatusRef.setShowStatus(1);           //是否显示：0不显示 1显示'
                fieldStatusRef.setMustStatus(1);  //是否必填：0非必填 1必填
                fieldStatusRef.setLastUpdateTime(new Date());
                fieldStatusRefList.add(fieldStatusRef);
            }

            fieldStatusRefRepository.saveAll(fieldStatusRefList);

            if (hierarchySave.getAreaId() != null) {
                ApprovalProcessUser approvalProcessUser = new ApprovalProcessUser();
                approvalProcessUser.setAreaTagId(hierarchySave.getTagId());
                approvalProcessUser.setAreaId(hierarchySave.getAreaId());
                approvalProcessUser.setOrgId(hierarchySave.getOrgId());
                approvalProcessUser.setLastUpdateTime(new Date());
                approvalProcessUser.setStatus(0);//状态：0停用 1启用
                approvalProcessUserRepository.save(approvalProcessUser);
            }
        } else {//编辑
            if (hierarchySave.getAreaId() != null) {
                ApprovalProcessUser apUser = approvalProcessUserRepository.findByOrgId(hierarchySave.getOrgId());
                if (apUser == null) {//新增
                    ApprovalProcessUser approvalProcessUser = new ApprovalProcessUser();
                    approvalProcessUser.setAreaTagId(hierarchySave.getTagId());
                    approvalProcessUser.setAreaId(hierarchySave.getAreaId());
                    approvalProcessUser.setOrgId(hierarchySave.getOrgId());
                    approvalProcessUser.setLastUpdateTime(new Date());
                    approvalProcessUser.setStatus(0);//状态：0停用 1启用
                    approvalProcessUserRepository.save(approvalProcessUser);
                } else {//修改
                    //机构区域变更，修改资格审批人设置表
                    if (hierarchySave.getTagId().longValue() != apUser.getAreaTagId() || hierarchySave.getAreaId().longValue() != apUser.getAreaId()) {
                        apUser.setAreaTagId(hierarchySave.getTagId());
                        apUser.setAreaId(hierarchySave.getAreaId());
                        apUser.setLastUpdateTime(new Date());
                        apUser.setStatus(0);//状态：0停用 1启用
                        approvalProcessUserRepository.save(apUser);
                    }
                }
            }


        //    优化修改名称房屋信息产权所有人名称跟着修改和智能锁列表的产权所有人名称
            List<House> houseList = houseRepository.findByOrgId(id);
            if (CollectionUtil.isNotEmpty(houseList)) {
                for (House house : houseList) {
                    house.setOwnerName(departmentVO.getName());
                }
            }
            List<SmartLock> smartLockList = smartLockRepository.findByOrgId(id);
            if (CollectionUtil.isNotEmpty(smartLockList)) {
                for (SmartLock smartLock : smartLockList) {
                    smartLock.setOrgName(departmentVO.getName());
                }
            }

        }

        return Result.success(null);
    }


    /*
     * 部门管理限制人数
     */
    public Result departmentLimitPeople(String token, Long depId, Integer maxNum) {
        LOG.info("---DepartmentService departmentLimitPeople accessToken={},depId={},maxNum={}", token, depId, maxNum);

        try {

            if (maxNum == null) {
                return Result.fail("限制人数不能为空");
            }
            Optional<Department> existDepartmentOptional = departmentRepository.findById(depId);
            if (existDepartmentOptional == null) {
                return Result.fail("机构不存在或已删除！");
            }

            Department existDepartment = existDepartmentOptional.get();

            existDepartment.setMaxNum(maxNum);
            departmentRepository.save(existDepartment);
        } catch (Exception e) {
            LOG.error(e.getMessage(), e);
            return Result.fail("操作异常");
        }
        return Result.success(null);
    }

 /*   private void a(){

        //当前企业区域标签为：社区
        if(departmentHierarchyVO.getTagId() != null) {
            if (departmentHierarchyVO.getTagId().longValue() == 5) {

                //查询当前层级所有父级包含本身id
                String sql = " SELECT T2.id FROM ( SELECT @r AS _id,(SELECT @r := parent_id FROM `saas_department_hierarchy` WHERE id = _id) AS parent_id,@l := @l + 1 AS lvl FROM (SELECT @r := ?, @l := 0) vars,saas_department_hierarchy h WHERE @r <> 0 AND parent_id >= 0 ) T1 " +
                        "JOIN saas_department_hierarchy T2 ON T1._id = T2.id ORDER BY T1.lvl  ";
                List<Long> topIds = jdbcTemplate.queryForList(sql, new Object[]{hierarchySave.getId()}, Long.class);

                //按层级关系往上查找区域标签id是区，记录每个节点
                List<DepartmentHierarchy> hierarchyList = new ArrayList<>();
                for (Long hid : topIds) {
                    DepartmentHierarchy hierarchy = departmentHierarchyRepository.findById(hid).get();
                    hierarchyList.add(hierarchy);
                    if (hierarchy.getTagId().longValue() == 3) {  //区域标签id是区为止
                        break;
                    }
                }

                List<Long> orgIdList = hierarchyList.stream().map(DepartmentHierarchy::getOrgId).collect(Collectors.toList());
                List<ApprovalProcessNode> approvalProcessNodeList = approvalProcessNodeRepository.findByOrgIdIn(orgIdList);
                if (approvalProcessNodeList.size() == 0) {  //如果没数据,继续下面处理

                    DepartmentHierarchy dh = hierarchyList.get(hierarchyList.size() - 1);
                    if (dh.getTagId().longValue() == 3) {  //区域标签id是区

                        //区下所有子集
                        List<Long> hids = allChildByHierarchy(dh.getId());
                        List<DepartmentHierarchy> departmentHierarchyList = departmentHierarchyRepository.findByIdIn(hids);

                        List<DepartmentHierarchy> allCommunity = new ArrayList<>();
                        for (DepartmentHierarchy d : departmentHierarchyList) {
                            if (d.getTagId().longValue() == 5) {
                                allCommunity.add(d);   //获取该区下所有社区
                            }
                        }

                        //默认审批流程定义表
                        ApprovalProcessDefinition approvalProcessDefinition = new ApprovalProcessDefinition();
                        //所有标签集
                        List<DepartmentTag> departmentTagList = departmentTagRepository.findAll();

                        String approvalProcessIds = "";
                        String processTagName = "";
                        //流程标签id
                        List<Long> tagList = new ArrayList<>();

                        //流程节点数据
                        StringBuffer currentApprovalProcess = new StringBuffer();
                        StringBuffer processOrgName = new StringBuffer();
                        List<Long> orgIds = new ArrayList<>();

                        for (DepartmentHierarchy d1 : hierarchyList) {
                            tagList.add(d1.getTagId());
                            approvalProcessIds += d1.getTagId() + ",";
                            for (DepartmentTag departmentTag : departmentTagList) {
                                if (departmentTag.getId().equals(d1.getTagId())) {
                                    processTagName += departmentTag.getTagName() + "->";
                                    break;
                                }
                            }

                            orgIds.add(d1.getOrgId());
                            currentApprovalProcess.append(d1.getOrgId()).append(",");
                            processOrgName.append(d1.getName()).append("->");

                        }
                        approvalProcessDefinition.setApprovalProcess(approvalProcessIds.substring(0, approvalProcessIds.lastIndexOf(",")));
                        approvalProcessDefinition.setProcessTagName(processTagName.substring(0, processTagName.lastIndexOf("->")));
                        ApprovalProcessDefinition definitionSave = approvalProcessDefinitionRepository.save(approvalProcessDefinition);

                        //审批流程定义节点明细表
                        List<ApprovalProcessDetail> approvalProcessDetailList = new ArrayList<>();
                        for (Long orgId : orgIds) {
                            ApprovalProcessDetail approvalProcessDetail = new ApprovalProcessDetail();
                            approvalProcessDetail.setOrgId(orgId);
                            approvalProcessDetail.setProcessDefinitionId(definitionSave.getId());
                            approvalProcessDetailList.add(approvalProcessDetail);
                        }
                        approvalProcessDetailRepository.saveAll(approvalProcessDetailList);

                        //审批流程表
                        ApprovalProcess approvalProcess = new ApprovalProcess();

                        approvalProcess.setDefaultProcessId(definitionSave.getId());
                        approvalProcess.setCommunityId(hierarchySave.getAreaId());  //当前企业区域标签为：社区
                        approvalProcess.setDistrictId(dh.getAreaId());  //区域是区
                        approvalProcess.setType(0);
                        approvalProcess.setProcessId(definitionSave.getId());
                        approvalProcess.setProcessStatus(1);
                        approvalProcess.setLastUpdateTime(new Date());
                        approvalProcess.setCreateTime(new Date());

                        ApprovalProcess approvalProcessInfo = approvalProcessRepository.save(approvalProcess);

                        //审批流程节点明细表
                        String approvalProcessPoint = definitionSave.getApprovalProcess();
                        String[] split = approvalProcessPoint.split(",");
                        //所有社区的企业信息
                        List<DepartmentHierarchy> communityDepartmentHierarchy = new ArrayList<>();

                        Long orgId = orgIds.get(0);  //只生成一条org是初始节点的数据
                        ApprovalProcessNode approvalProcessNode = new ApprovalProcessNode();
                        approvalProcessNode.setOrgId(orgId);
                        approvalProcessNode.setApprovalProcessId(approvalProcessInfo.getId());
                        String currentApprovalProcessIds = "";
                        if (StringUtils.isNotBlank(currentApprovalProcess)) {
                            currentApprovalProcessIds = currentApprovalProcess.substring(0, currentApprovalProcess.lastIndexOf(","));
                        }
                        String processOrgNames = "";
                        if (StringUtils.isNotBlank(processOrgName)) {
                            processOrgNames = processOrgName.substring(0, processOrgName.lastIndexOf("->"));
                        }
                        approvalProcessNode.setCurrentApprovalProcess(currentApprovalProcessIds);
                        approvalProcessNode.setProcessOrgName(processOrgNames);
                        approvalProcessNode.setStatus(0);
                        approvalProcessNode.setLastUpdateTime(new Date());
                        approvalProcessNodeRepository.save(approvalProcessNode);



                    }
                }

            }
        }

    }*/


    public Result permissionList(String accessToken, Long roleId) {
        LOG.info("---RoleService permissionList accessToken={},roleId={}", accessToken, roleId);

        try {
            StringBuffer sql = new StringBuffer("SELECT id, parent_id, NAME, TYPE, url, method, CODE, sortby, icon FROM saas_permission WHERE master_show=1  ORDER BY parent_id,sortby");
            StringBuffer rolePermSql = new StringBuffer("SELECT permission_id FROM saas_role_app_ref WHERE role_id = ? ORDER BY permission_id");

            List<PermissionVO> list = jdbcTemplate.query(sql.toString(), new PermissionRowMapper());
            List<Map<String, Object>> rolePermList = jdbcTemplate.queryForList(rolePermSql.toString(), roleId);

            if (list == null || list.isEmpty()) {
                return Result.success(null);
            }

            checkSelect(list, rolePermList, "permission_id");

            return Result.success(list);
        } catch (Exception e) {
            LOG.error(e.getMessage(), e);
            return Result.fail();
        }
    }

    /**
     * 设置已有权限
     *
     * @param list
     * @param rolePermList
     * @param permIdColumn
     * @author chensenrong
     */
    private void checkSelect(List<PermissionVO> list, List<Map<String, Object>> rolePermList, String permIdColumn) {
        for (PermissionVO vo : list) {
            if (hasPerm(vo.getId(), rolePermList, permIdColumn)) {
                vo.setCheck(true);
            } else {
                vo.setCheck(false);
            }
        }
    }

    /**
     * 判断是否拥有权限
     *
     * @param id
     * @param rolePermList
     * @param permIdColumn
     * @return
     * @author chensenrong
     */
    private boolean hasPerm(Long id, List<Map<String, Object>> rolePermList, String permIdColumn) {
        for (Map<String, Object> map : rolePermList) {
            Object perIdObj = map.get(permIdColumn);
            if (perIdObj == null) {
                continue;
            }

            Long perId = Long.valueOf(perIdObj.toString());
            if (id.longValue() == perId.longValue()) {
                return true;
            }
        }

        return false;
    }

    public Result delete(String accessToken, Long id) {
        LOG.info("DepartmentService delete accessToken={},id={}", accessToken, id);

        Optional<DepartmentHierarchy> optional = departmentHierarchyRepository.findById(id);
        if (!optional.isPresent()) {
            return Result.fail("机构不存在");
        }

        DepartmentHierarchy departmentHierarchy = optional.get();
        if (departmentHierarchyRepository.existsByParentId(departmentHierarchy.getId())) {
            return Result.fail("当前机构存在下级机构，无法删除");
        }

        if (departmentRepository.existsByParentId(departmentHierarchy.getOrgId())) {
            return Result.fail("当前机构存在下级部门，无法删除");
        }
        Long depId = departmentHierarchy.getOrgId();

        StringBuffer sbSql = new StringBuffer("SELECT * FROM `saas_user_department_ref` WHERE 1=1 AND `dep_id` = " + depId);
        List<UserDepartment> userDepartmentList = jdbcTemplate.query(sbSql.toString(), new BeanPropertyRowMapper<>(UserDepartment.class));

        //主管理员角色
        Role role = roleRepository.findByOrgIdAndPropertyAndType(depId, 2, 1).get(0);
        UserRole userRole = userRoleRepository.findByRoleId(role.getId()).get(0);

        //普通成员列表
        List<UserDepartment> udList = new ArrayList<>();
        for (UserDepartment ud : userDepartmentList) {
            if (!ud.getUserId().equals(userRole.getUserId())) {
                udList.add(ud);
            }
        }

        if (udList.size() > 0) {
            return Result.fail("当前机构存在部门成员，无法删除");
        }

        List<Role> roleList = roleRepository.findByOrgIdAndPropertyAndType(depId, 2, 0);
        if (roleList.size() > 0) {
            return Result.fail("当前机构存在普通角色，无法删除");
        }

        departmentHierarchyRepository.deleteById(id);
        departmentRepository.deleteById(depId);

        //删除主管理员
        userRoleRepository.deleteByRoleId(role.getId());
        userDepartmentRepository.deleteByUserId(userRole.getUserId());
        roleRepository.deleteById(role.getId());
        qYUserRepository.deleteById(userRole.getUserId());

        return Result.success(null);
    }

    /**
     * 机构层级-修改状态
     *
     * @param filter
     * @return
     */
    public Result UpdateStatus(String accessToken, DepartmentHierarchyVO filter) {
        LOG.info("DepartmentService UpdateStatus accessToken={},filter={}", accessToken, filter);
        Optional<DepartmentHierarchy> optional = departmentHierarchyRepository.findById(filter.getId());
        if (optional.isPresent()) {
            DepartmentHierarchy departmentHierarchy = optional.get();
            departmentHierarchy.setStatus(filter.getStatus());
            departmentHierarchyRepository.save(departmentHierarchy);
        }
        return Result.success(null);
    }

    public Result updateMerchantsTypeStatus(String accessToken, DepartmentHierarchyVO filter) {
        LOG.info("DepartmentService updateMerchantsTypeStatus accessToken={},filter={}", accessToken, filter);
        Optional<DepartmentHierarchy> optional = departmentHierarchyRepository.findById(filter.getId());
        if (optional.isPresent()) {
            DepartmentHierarchy departmentHierarchy = optional.get();
            departmentHierarchy.setMerchantsType(filter.getMerchantsType());
            departmentHierarchyRepository.save(departmentHierarchy);
        }
        return Result.success(null);
    }

    public Result updateBindAuitStatus(String accessToken, DepartmentHierarchyVO filter) {
        LOG.info("DepartmentService updateBindAuitStatus accessToken={},filter={}", accessToken, filter);
        Optional<DepartmentHierarchy> optional = departmentHierarchyRepository.findById(filter.getId());
        if (optional.isPresent()) {
            DepartmentHierarchy departmentHierarchy = optional.get();
            departmentHierarchy.setBindAuitStatus(filter.getBindAuitStatus());
            departmentHierarchyRepository.save(departmentHierarchy);
        }
        return Result.success(null);
    }

    public Result defaultProcessList(String accessToken, Long id) {
        LOG.info("DepartmentService defaultProcessList accessToken={},id={}", accessToken, id);

        try {
            if (id == null) {
                return Result.fail("机构层级id为空");
            }

            //查询当前层级所有父级包含本身id
            String sql = " SELECT T2.id FROM ( SELECT @r AS _id,(SELECT @r := parent_id FROM `saas_department_hierarchy` WHERE id = _id) AS parent_id,@l := @l + 1 AS lvl FROM (SELECT @r := ?, @l := 0) vars,saas_department_hierarchy h WHERE @r <> 0 AND parent_id >= 0 ) T1 " +
                    "JOIN saas_department_hierarchy T2 ON T1._id = T2.id ORDER BY T1.lvl  ";
            List<Long> topIds = jdbcTemplate.queryForList(sql, new Object[]{id}, Long.class);

            List<DepartmentHierarchy> hierarchyList = new ArrayList<>();
            for (Long hid : topIds) {
                DepartmentHierarchy hierarchy = departmentHierarchyRepository.findById(hid).get();
                hierarchyList.add(hierarchy);
                if (hierarchy.getTagId().longValue() == 3) {  //区域标签id是区为止
                    break;
                }
            }

            List<Long> tagIdList = new ArrayList<>();
            List<String> tagNameList = new ArrayList<>();

            List<DepartmentTag> departmentTagList = departmentTagRepository.findAll();
            for (DepartmentHierarchy dh : hierarchyList) {
                tagIdList.add(dh.getTagId());
                for (DepartmentTag dt : departmentTagList) {
                    if (dh.getTagId().equals(dt.getId())) {
                        tagNameList.add(dt.getTagName());
                    }
                }

            }

            Map<String, Object> result = new HashMap<>();

            result.put("approvalProcess", tagIdList);
            result.put("processTagName", tagNameList);
            result.put("id", "");


            return Result.success(result);
        } catch (Exception e) {
            System.out.println(e.getMessage());
            return Result.fail();
        }
    }

    public Result departmentTag(String accessToken) {
        LOG.info("DepartmentService departmentTag accessToken={}", accessToken);

        List<DepartmentTag> departmentTagList = departmentTagRepository.findAll();

        ApiData<DepartmentTagVO> apiData = new ApiData();
        for (DepartmentTag departmentTag : departmentTagList) {
            DepartmentTagVO departmentTagVO = new DepartmentTagVO();
            BeanUtils.copyProperties(departmentTag, departmentTagVO);
            apiData.getData().add(departmentTagVO);

        }
        apiData.setTotal(new Long(apiData.getData().size()));
        return Result.success(apiData);
    }

    public Result departmentEnterpriseTag(String accessToken) {
        LOG.info("DepartmentService departmentEnterpriseTag accessToken={}", accessToken);

        List<DepartmentEnterpriseTag> departmentEnterpriseTagList = departmentEnterpriseTagRepository.findAll();

        ApiData<DepartmentEnterpriseTagVO> apiData = new ApiData();
        for (DepartmentEnterpriseTag departmentEnterpriseTag : departmentEnterpriseTagList) {
            DepartmentEnterpriseTagVO departmentEnterpriseTagVO = new DepartmentEnterpriseTagVO();
            BeanUtils.copyProperties(departmentEnterpriseTag, departmentEnterpriseTagVO);
            apiData.getData().add(departmentEnterpriseTagVO);

        }
        apiData.setTotal(new Long(apiData.getData().size()));
        return Result.success(apiData);
    }

    //部门列表
    public Result departmentPages(String accessToken, DepartmentVO filter) {
        LOG.info("DepartmentService departmentPages accessToken={},filter={}", accessToken, JSON.toJSONString(filter));

        ApiData<Map<String, Object>> apiData = new ApiData<>();
        try {

            StringBuffer sql = new StringBuffer(
                    "SELECT  DISTINCT d.`id`,d.`parent_id` AS parentId,d.`name`,a1.name AS provinceName,a2.name AS cityName,a3.name AS districtName,a4.name AS streetName,a5.`name` AS communityName FROM `saas_department` d \n" +
                            "LEFT JOIN `sys_area` a1 ON d.`province_id`=a1.id LEFT JOIN `sys_area` a2 ON d.`city_id`=a2.id LEFT JOIN `sys_area` a3 ON d.`district_id`=a3.id\n" +
                            "LEFT JOIN `sys_area` a4 ON d.`street_id`=a4.id \n" +
                            "LEFT JOIN `sys_area` a5 ON d.`community_id`=a5.id WHERE 1=1 ");

            StringBuffer where = new StringBuffer(" ");
            List<Object> args = new ArrayList<>();

            if (filter.getAreaId() != null) {
                List<Long> childAreaId = allChildByArea(filter.getAreaId());
                childAreaId.add(filter.getAreaId());

                StringBuffer area = new StringBuffer();

                childAreaId.forEach(a -> {
                    area.append(a).append(",");
                });
                String areasql = area.toString().substring(0, area.toString().lastIndexOf(","));

                where.append(" AND ( d.`province_id` in ( ").append(areasql).append(") or ")
                        .append(" d.`city_id` in ( ").append(areasql).append(") or ")
                        .append(" d.`district_id` in ( ").append(areasql).append(") or ")
                        .append(" d.`street_id` in ( ").append(areasql).append(") or ")
                        .append(" d.`community_id` in ( ").append(areasql).append(") ) ");

            }

            if (StringUtils.isNotBlank(filter.getName())) {
                where.append(" AND name LIKE ? ");
                args.add("%" + filter.getName() + "%");
            }


            String totalCount = "SELECT COUNT(0) FROM (" + sql + ") c ";
            // 查询总记录数
            Long total = jdbcTemplate.queryForObject(totalCount, Long.class, args.toArray());
            if (total == 0) {
                return Result.success(null);
            }

            List<Map<String, Object>> mapList = jdbcTemplate.queryForList(sql.toString(), args.toArray());
            mapList.forEach(m -> {
                Long id = (Long) m.get("id");
                String num = "SELECT COUNT(0) FROM `saas_user_department_ref` d INNER JOIN `saas_user` u ON u.id=d.user_id WHERE u.status!=2  AND d.dep_id=? \n";
                Long count = jdbcTemplate.queryForObject(num, new Object[]{id}, Long.class);
                m.put("num", count);
            });
            // 查询分页数据
            apiData.setData(mapList);
            apiData.setTotal(total);
            return Result.success(apiData);
        } catch (Exception e) {
            LOG.error(e.getMessage(), e);
            return Result.fail();
        }
    }

    //新增子部门
    public Result addChildDepartment(String accessToken, DepartmentVO departmentVO) {
        LOG.info("---DepartmentService addChildDepartment accessToken={},departmentVO={}", accessToken, departmentVO);

        try {

            if (departmentVO == null && departmentVO.getParentId() == null) {
                return Result.fail("上级部门为空");
            }
            Department parentDepartment = departmentRepository.findById(departmentVO.getParentId()).get();
            if (parentDepartment == null) {
                return Result.fail("上级部门不存在");
            }
            Department department = departmentRepository.findById(departmentVO.getParentId()).get();
            Department child = new Department();
            departmentVO.setCode(buildCodeByDepartment(departmentVO.getParentId()));
            departmentVO.setStatus(0);
            departmentVO.setSortby(department.getSortby() + 1);
            departmentVO.setType(3);
            departmentVO.setCreateTime(new Date());
            departmentVO.setActivateStatus(1);
            Department existDepartment = departmentRepository.findAllByParentIdAndName(departmentVO.getParentId(), departmentVO.getName());
            if (existDepartment != null) {
                return Result.fail("名称已被使用");
            }
            BeanUtils.copyProperties(departmentVO, child);
            departmentRepository.save(child);
            return Result.success(null);
        } catch (Exception e) {
            LOG.error(e.getMessage(), e);
            return Result.fail();
        }
    }


    //编辑子部门
    @Transactional(rollbackFor = Exception.class)
    public Result updateDepartment(String accessToken, DepartmentVO departmentVO) {
        LOG.info("---DepartmentService updateDepartment accessToken={},departmentVO={}", accessToken, departmentVO);

        try {

            if (departmentVO == null) {
                return Result.fail();
            }
            Long parentId = departmentVO.getParentId();
            String name = departmentVO.getName();
            Long depId = departmentVO.getId();
            if (depId == null) {
                return Result.fail("部门id不能为空");
            }
            if (StringUtils.isBlank(name)) {
                return Result.fail("部门名称不能为空");
            }
            Optional<Department> departmentDetail = departmentRepository.findById(depId);
            if (departmentDetail == null) {
                return Result.fail("部门信息不存在或已删除");
            }
            Department existDepartment = departmentRepository.findAllByParentIdAndName(departmentVO.getParentId(), departmentVO.getName());
            if (existDepartment != null && existDepartment.getId() != departmentVO.getId()) {
                return Result.fail("名称已被使用");
            }
            Optional<Department> parentDepartmentOptional = departmentRepository.findById(parentId);
            if (parentDepartmentOptional == null) {
                return Result.fail("上级部门信息不存在或已删除");
            }
            Department department = departmentDetail.get();

            if (department.getParentId() ==0 && parentId !=0){
                return Result.fail("一级部门的上级部门只能是无！");
            }

            String childCode = department.getCode();
            department.setName(name);
            department.setParentId(parentId);
            String newCode = buildCodeByDepartment(parentId);
            department.setCode(newCode);
            Department save = departmentRepository.save(department);
            if (save != null) {
                List<Long> idsList = allChild(depId);
                List<Department> allDepartment = departmentRepository.findByIdIn(idsList);
                for (Department childDepartment : allDepartment) {
                    StringBuffer buffer = new StringBuffer(childDepartment.getCode());
                    buffer.replace(0, childCode.length(), save.getCode());
                    childDepartment.setCode(String.valueOf(buffer));
                    departmentRepository.save(childDepartment);
                }
            } else {
                return Result.fail();
            }
        } catch (Exception e) {
            LOG.error(e.getMessage(), e);
            return Result.fail();
        }
        return Result.success(null);
    }


    //部门管理删除部门
    public Result deleteDepartment(String accessToken, Long depId) {
        LOG.info("---DepartmentService deleteDepartment accessToken={}", accessToken);

        try {

            if (depId == null) {
                return Result.fail();
            }
            Optional<Department> existDepartment = departmentRepository.findById(depId);
            if (existDepartment == null) {
                return Result.fail("部门不存在或已删除");
            }
            List<User> existUser = new ArrayList<>();
            List<UserDepartment> userDepartmentList = userDepartmentRepository.findByDepId(depId);
            if (userDepartmentList != null && userDepartmentList.size() > 0) {
                userDepartmentList = userDepartmentList.stream().distinct().collect(Collectors.toList());
            }
            for (UserDepartment userDepartment : userDepartmentList) {
                User user = qYUserRepository.findById(userDepartment.getUserId()).get();
                existUser.add(user);
            }
            if (existUser != null && existUser.size() > 0) {
                return Result.fail("部门下存在部门成员或已被授权其他用户不能删除");
            }
            StringBuffer childDepIds = new StringBuffer();
            String sql = "SELECT id FROM ( SELECT t1.id,IF(FIND_IN_SET(parent_id, @pids) > 0,@pids := CONCAT(@pids, ',', id),0) AS ischild FROM ( SELECT id,parent_id FROM `saas_department` t ORDER BY parent_id, id ) t1,(SELECT @pids := ?) t2 ) t3 WHERE ischild != 0 \n";
            List<Long> ids = jdbcTemplate.queryForList(sql, new Object[]{depId}, Long.class);
            for (Long id : ids) {
                childDepIds.append(id).append(",");
            }
            childDepIds.append(depId);
            StringBuffer sbSql = new StringBuffer("SELECT COUNT(0) AS num FROM `saas_user_department_ref` WHERE 1=1 ");
            if (!StringUtils.isBlank(childDepIds.toString())) {
                sbSql.append("  AND  `dep_id`  IN  (" + childDepIds.toString() + ")  ");
            }
            Map<String, Object> childPeople = jdbcTemplate.queryForMap(sbSql.toString());
            if (childPeople != null && childPeople.get("num") != null) {
                Long num = (Long) childPeople.get("num");
                if (num > 0) {
                    return Result.fail("子部门下存在部门成员不能删除");
                }
            }
            departmentRepository.deleteById(depId);
            departmentRepository.deleteByParentId(depId);
            return Result.success(null);
        } catch (Exception e) {
            LOG.error(e.getMessage(), e);
            return Result.fail();
        }
    }

    //生成code  [department]
    private String buildCodeByDepartment(Long parentId) {
        //找同级Code
        boolean b = departmentRepository.existsByParentId(parentId);
        String str, parentCodeStr;
        int code;
        if (!b) {
            //找父级Code
            Optional<Department> optionalById = departmentRepository.findById(parentId);
            //顶部Code
            if (parentId == 0) {
                return "001";
            }
            parentCodeStr = optionalById.get().getCode();
            return parentCodeStr + "001";
        }
        Long maxId = departmentRepository.findByParentIdMaxId(parentId);
        int index;
        Optional<Department> optionalByParentId = departmentRepository.findById(maxId);
        if (StrUtil.isNotEmpty(optionalByParentId.get().getCode())) {
            code = Integer.parseInt(optionalByParentId.get().getCode()) + 1;
            index = optionalByParentId.get().getCode().length();
        } else {
            code = 1;
            index = 1;
        }
        str = "000" + code;
        String codeStr = str.substring(str.length() - index);

        return codeStr;
    }

    //生成code (departmentHierarchy)
    private String buildCodeByDepartmentHierarchy(Long parentId) {
        //找同级Code
        boolean b = departmentHierarchyRepository.existsByParentId(parentId);
        String str, parentCodeStr;
        // int code;
        long code;
        if (!b) {
            //找父级Code
            Optional<DepartmentHierarchy> optionalById = departmentHierarchyRepository.findById(parentId);
            //顶部Code
            if (parentId == 0) {
                return "001";
            }
            parentCodeStr = optionalById.get().getCode();
            return parentCodeStr + "001";
        }
        Long maxId = departmentHierarchyRepository.findByParentIdMaxId(parentId);
        Optional<DepartmentHierarchy> optionalByParentId = departmentHierarchyRepository.findById(maxId);
        //修复bug，数据类型错误，使用int太小了
        String code2 = optionalByParentId.get().getCode();
        long l = Long.parseLong(code2);
        code =  l + 1 ;
        // int i = Integer.parseInt(optionalByParentId.get().getCode()) + 1 ;
        str = "000" + code;
        String codeStr = str.substring(str.length() - optionalByParentId.get().getCode().length());

        return codeStr;
    }


    //查找当前部门节点所有节点(不包含当前节点)saas_department
    public List<Long> allChild(Long depId) {
        String sql = " select id from ( select t1.id,if(find_in_set(parent_id, @pids) > 0,@pids := concat(@pids, ',', id),0) as ischild from ( select id,parent_id from `saas_department` t order by parent_id, id ) t1,(select @pids := ?) t2 ) t3 where ischild != 0 \n";
        return jdbcTemplate.queryForList(sql, new Object[]{depId}, Long.class);
    }

    //查找当前区域节点所有节点(不包含当前节点)sys_area
    public List<Long> allChildByArea(Long areaId) {
        String sql = " select id from ( select t1.id,if(find_in_set(parent_id, @pids) > 0,@pids := concat(@pids, ',', id),0) as ischild from ( select id,parent_id from `sys_area` t order by parent_id, id ) t1,(select @pids := ?) t2 ) t3 where ischild != 0 \n";
        return jdbcTemplate.queryForList(sql, new Object[]{areaId}, Long.class);
    }

    //查找当前机构层级节点所有节点(不包含当前节点)saas_department_hierarchy
    public List<Long> allChildByHierarchy(Long id) {
        String sql = " select id from ( select t1.id,if(find_in_set(parent_id, @pids) > 0,@pids := concat(@pids, ',', id),0) as ischild from ( select id,parent_id from `saas_department_hierarchy` t order by parent_id, id ) t1,(select @pids := ?) t2 ) t3 where ischild != 0 \n";
        return jdbcTemplate.queryForList(sql, new Object[]{id}, Long.class);
    }


}
